package com.greensam.pixelengine.service.impl;

import com.greensam.pixelengine.pojo.base.PaginationResponse;
import com.greensam.pixelengine.pojo.entity.*;
import com.greensam.pixelengine.pojo.query.SpaceUserPageQuery;
import com.greensam.pixelengine.repository.SpaceUserRepository;
import com.greensam.pixelengine.service.SpaceUserDataService;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @author Ma Chengrui
 * @since 2025/9/22 17:02
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SpaceUserDataServiceImpl implements SpaceUserDataService {

    private final JPAQueryFactory jpaQueryFactory;
    private final SpaceUserRepository spaceUserRepository;

    @Override
    public PaginationResponse<SpaceUserPo> pageSpaceUser(SpaceUserPageQuery pageQuery) {
        QSpaceUserPo su = QSpaceUserPo.spaceUserPo;
        BooleanBuilder condition = new BooleanBuilder();
        condition.and(su.delete.eq(Boolean.FALSE));
        if (Objects.nonNull(pageQuery.getSpaceId())) {
            condition.and(su.spaceId.eq(pageQuery.getSpaceId()));
        }
        if (Objects.nonNull(pageQuery.getUserId())) {
            condition.and(su.userId.eq(pageQuery.getUserId()));
        }
        if (Objects.nonNull(pageQuery.getRoleId())) {
            condition.and(su.roleId.eq(pageQuery.getRoleId()));
        }

        Long totalCount = jpaQueryFactory.select(su.id.countDistinct())
                .from(su)
                .where(condition)
                .fetchOne();
        if (Objects.isNull(totalCount) || totalCount == 0) {
            return PaginationResponse.empty(pageQuery.getPageSize(), pageQuery.getPageNum());
        }
        List<SpaceUserPo> result = jpaQueryFactory.selectFrom(su)
                .where(condition)
                .orderBy(su.updateTime.desc())
                .offset(pageQuery.offset())
                .limit(pageQuery.getPageSize())
                .fetch();
        return PaginationResponse.page(result, totalCount, pageQuery.getPageSize(), pageQuery.getPageNum());
    }

    @Override
    public Optional<SpaceUserPo> getSpaceUserById(Long id) {
        QSpaceUserPo su = QSpaceUserPo.spaceUserPo;
        return Optional.ofNullable(jpaQueryFactory.selectFrom(su)
                .where(su.id.eq(id)
                        .and(su.delete.eq(Boolean.FALSE)))
                .fetchOne());
    }

    @Override
    public Optional<SpaceUserPo> getSpaceUserByUserId(Long userId) {
        QSpaceUserPo su = QSpaceUserPo.spaceUserPo;
        return Optional.ofNullable(jpaQueryFactory.selectFrom(su)
                .where(su.userId.eq(userId)
                        .and(su.delete.eq(Boolean.FALSE)))
                .fetchOne());
    }

    @Override
    public Optional<SpaceUserPo> getSpaceUserByUserIdAndSpaceId(Long userId, Long spaceId) {
        QSpaceUserPo su = QSpaceUserPo.spaceUserPo;
        return Optional.ofNullable(jpaQueryFactory.selectFrom(su)
                .where(su.userId.eq(userId)
                        .and(su.spaceId.eq(spaceId))
                        .and(su.delete.eq(Boolean.FALSE)))
                .fetchOne());
    }

    @Override
    public SpaceUserPo save(SpaceUserPo spaceUserPo) {
        if (Objects.isNull(spaceUserPo)) {
            return null;
        }
        return spaceUserRepository.save(spaceUserPo);
    }

    @Override
    public List<SpaceUserPo> listSpaceUserByUserId(Long userId) {
        if (Objects.isNull(userId)) {
            return Collections.emptyList();
        }
        QSpaceUserPo su = QSpaceUserPo.spaceUserPo;
        return jpaQueryFactory.selectFrom(su)
                .where(su.userId.eq(userId)
                        .and(su.delete.eq(Boolean.FALSE)))
                .fetch();
    }
}
